package controller

import (
	"github.com/gin-gonic/gin"
	"shop-common/library/serializer"
	"shop-common/utils"
	"shop-common/utils/contextArgs"
	"shop-common/utils/pagehelper"
	"shop-common/utils/queryWrapper"
	"shop-sys/business"
	"shop-sys/pkg/code"
	"shop-sys/pkg/constant"
	"shop-sys/pkg/dto"
	"shop-sys/pkg/request"
)

type SysRoleController struct {
}

// @Tags 角色管理
// @Summary 保存角色
// @description: 保存角色
// @Security ApiKeyAuth
// @function: Save
// @Accept  json
// @Produce  json
// @Param data body request.SysRoleRequest true "请求参数"
// @Success 200 {object} string "{"code":0," result":{}, "message":"操作成功", "time":1618493448}"
// @Router /sys/role  [post]
func (r *SysRoleController) Save(ctx *gin.Context) {
	form := request.SysRoleRequest{}
	if err := serializer.Verify(ctx, &form); err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	userId, err := contextArgs.GetUserInternalId(ctx)
	if err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	// 角色要去重判断。
	exist, err := business.ServiceImpl().SysRoleService.CheckRoleNameExist(form.RoleName)
	if err != nil {
		serializer.Fail(ctx, serializer.PublicCreateErr)
		return
	} else if exist {
		serializer.Fail(ctx, code.StatusText(code.RoleExist))
		return
	}

	roleId, err := business.ServiceImpl().SysRoleService.SaveRoleAndRoleMenu(&form, userId)
	if err != nil {
		serializer.Fail(ctx, serializer.PublicCreateErr)
		return
	}

	//修改redis里的角色信息
	_, err = business.ServiceImpl().SysMenuService.FindByRoleIdPerms([]uint{roleId})
	if err != nil {
		serializer.Fail(ctx, serializer.PublicCreateErr)
		return
	}

	serializer.Success(ctx, "")
}

// @Tags 角色管理
// @description: 角色列表
// @Summary 角色列表
// @Security ApiKeyAuth
// @function: Page
// @Accept  json
// @Produce  json
// @Param current query string false "当前页，默认1"
// @Param size query string false "每页大小，默认10"
// @Param keyword query string false "keyword"
// @Success 200 {object} string "{"code":0," result":{}, "message":"操作成功", "time":1618493448}"
// @Router /sys/role/page [get]
func (r *SysRoleController) Page(ctx *gin.Context) {
	form := pagehelper.SearchPageRequest{}
	if err := serializer.Verify(ctx, &form); err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	role, err := business.ServiceImpl().SysRoleService.PageRole(&form)
	if err != nil {
		serializer.Fail(ctx, serializer.PublicQueryErr)
		return
	}

	serializer.SuccessData(ctx, "", role)
}

// @Tags 角色管理
// @description: 全部角色列表
// @Summary 全部角色列表
// @Security ApiKeyAuth
// @function: List
// @Accept  json
// @Produce  json
// @Param keyword query string false "keyword"
// @Success 200 {object} string "{"code":0," result":{}, "message":"操作成功", "time":1618493448}"
// @Router /sys/role/list [get]
func (r *SysRoleController) List(ctx *gin.Context) {
	form := pagehelper.SearchPageRequest{}
	if err := serializer.Verify(ctx, &form); err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	var pair *queryWrapper.WherePair
	if form.Keyword != "" {
		pair = queryWrapper.Like("role_name", form.Keyword)
	}

	role, err := business.ServiceImpl().SysRoleService.FindRole(pair)
	if err != nil {
		serializer.Fail(ctx, serializer.PublicQueryErr)
		return
	}

	serializer.SuccessData(ctx, "", role)
}

// @Tags 角色管理
// @description: 删除角色
// @Summary 删除角色
// @Security ApiKeyAuth
// @function: Delete
// @Accept  json
// @Produce  json
// @Param rids query []string false "roleIds"
// @Success 200 {object} string "{"code":0," result":{}, "message":"操作成功", "time":1618493448}"
// @Router /sys/role [delete]
func (r *SysRoleController) Delete(ctx *gin.Context) {
	form := request.SysRoleDeleteRequest{}
	if err := serializer.Verify(ctx, &form); err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	roleIds, err := business.ServiceImpl().SysRoleService.FindInRoleIds(form.RoleIds)
	if err != nil || len(roleIds) == 0 {
		serializer.Fail(ctx, "未找到需要删除的数据!")
		return
	}

	isSuperAdmin := utils.UintIncludes(roleIds, constant.SUPER_ADMIN_ID)
	if isSuperAdmin {
		serializer.Fail(ctx, "超级管理员不能删除!")
		return
	}

	err = business.ServiceImpl().SysRoleService.DeleteBatch(roleIds)
	if err != nil {
		serializer.Fail(ctx, serializer.PublicDeleteErr)
		return
	}

	serializer.Success(ctx, "")
}

// @Tags 角色管理
// @description: 修改角色
// @Summary 修改角色
// @Security ApiKeyAuth
// @function: Update
// @Accept  json
// @Produce  json
// @Param data body request.SysRoleRequest true "请求参数"
// @Success 200 {object} string "{"code":0," result":{}, "message":"操作成功", "time":1618493448}"
// @Router /sys/role  [put]
func (r *SysRoleController) Update(ctx *gin.Context) {
	form := request.SysRoleRequest{}
	if err := serializer.Verify(ctx, &form); err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	if form.RoleId <= 0 {
		serializer.Fail(ctx, "roleId不能为空")
		return
	}

	sysRole, err := business.ServiceImpl().SysRoleService.FindById(form.RoleId)
	if err != nil {
		serializer.Fail(ctx, serializer.PublicUpdateErr)
		return
	}

	err = business.ServiceImpl().SysRoleService.UpdateRoleAndRoleMenu(&form, sysRole.RoleId)

	if err != nil {
		serializer.Fail(ctx, serializer.PublicUpdateErr)
		return
	}

	_, err = business.ServiceImpl().SysMenuService.FindByRoleIdPerms([]uint{sysRole.RoleId})
	if err != nil {
		serializer.Fail(ctx, serializer.PublicUpdateErr)
		return
	}

	serializer.Success(ctx, "")
}

// @Tags 角色管理
// @Summary 角色信息
// @Description: 角色信息
// @Security ApiKeyAuth
// @function: Info
// @Accept  json
// @Produce  json
// @Param roleId query string true "角色ID"
// @Success 200 {object} string "{"code":0," result":{}, "message":"操作成功", "time":1618493448}"
// @Router /sys/role/info/{roleId} [get]
func (r *SysRoleController) Info(ctx *gin.Context) {
	roleId, err := contextArgs.GetUriIntPath(ctx, "roleId")
	if err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	sysRole, err := business.ServiceImpl().SysRoleService.FindById(roleId)
	if err != nil {
		serializer.Fail(ctx, err.Error())
		return
	}

	if sysRole == nil {
		serializer.Fail(ctx, "获取角色信息失败!")
		return
	}

	//查询角色对应的菜单
	serializer.SuccessData(ctx, "", &dto.SysRoleInfoDTO{
		RoleId:    sysRole.RoleId,
		RoleName:  sysRole.RoleName,
		Remark:    sysRole.Remark,
		CreatedAt: sysRole.CreatedAt.UnixNano(),
		MenuIds:   business.ServiceImpl().SysMenuService.FindMenuIdByRoleId(sysRole.RoleId),
	})
}
